package com.github.data_manage.domain.vo

import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.github.data_manage.config.SystemException
import com.github.data_manage.domain.po.Fund
import com.github.data_manage.enum.NumberRelation
import com.github.data_manage.enum.SortType
import com.github.data_manage.util.ArrayToStringDeSerialize
import com.github.data_manage.util.StringToArraySerialize
import org.springframework.data.domain.Sort
import org.springframework.util.StringUtils
import java.math.BigDecimal

/**
 *@author CHN
 *@since 2024-08-10 16:23
 */
open class FundPageParam : BasePageVoParam() {

    companion object {
        private val NAME_MAP = mapOf(
            Pair("yearNav", "year_nav"),
            Pair("yearStandardDeviation", "year_standard_deviation"),
            Pair("fundName", "fund_name"),
            Pair("fundShortName", "fund_short_name"),
            Pair("aum", "aum"),
            Pair("createDate", "create_date"),
            Pair("screenOverallRate", "t2.screen_overall_rate"),
            Pair("meetingRate", "t2.meeting_rate"),
            Pair("investmentRate", "t2.investment_rate"),
            Pair("riskRate", "t2.risk_rate"),
            Pair("keyManRate", "t2.key_man_rate"),
            Pair("businessRate", "t2.business_rate"),
            Pair("fundId", "f.fund_id"),
        )
    }

    open var strategyAum: String? = null

    open var geographicalDistribution: String? = null

    open var fundName: String? = null

    open var fundShortName: String? = null

    open var corePerson: String? = null

    open var aum: NumberRangeQuery? = null

    open var annualizedFluctuations: NumberRangeQuery? = null
    open var meetingRateFluctuations: NumberRangeQuery? = null
    open var investmentRateFluctuations: NumberRangeQuery? = null
    open var riskRateFluctuations: NumberRangeQuery? = null
    open var keymanRateFluctuations: NumberRangeQuery? = null
    open var businessRateFluctuations: NumberRangeQuery? = null
    open var screenOverallScoreFluctuations: NumberRangeQuery? = null

    open var annualizedReturns: NumberRangeQuery? = null

    open var invested: Boolean? = null

    open var screenOverallRateCondition: ScreenOverallRateQueryVo? = null

    open var screenOverallScore: BigDecimal? = null

    open var parentAumCondition: List<String>? = null

    open var childAumCondition: List<String>? = null

    open var companyCity: String? = null


    @get:JsonIgnore
    open val screenOverallRateConditionFilter: String
        get() = screenOverallRateConditionFilter()

    @get:JsonIgnore
    open val numberRelationFilter: String
        get() = buildNumberRelationFilter()

    @get:JsonIgnore
    open val sortBy: String
        get() = buildSortBy()

    @get:JsonIgnore
    open val parentAumFilter: String
        get() = parentAumFilter()

    @get:JsonIgnore
    open val childAumFilter: String
        get() = childAumFilter()

    private fun buildNumberRelationFilter(): String {
        val sb = StringBuilder()
        if (aum != null) {
            sb.append(" and f.aum").append(aum!!.relation.text).append(aum!!.value)
        }
        if (annualizedFluctuations != null) {
            sb.append(" and f.year_standard_deviation").append(annualizedFluctuations!!.relation.text)
                .append(annualizedFluctuations!!.value)
        }
        if (screenOverallScoreFluctuations != null) {
            sb.append(" and t2.screen_overall_rate").append(screenOverallScoreFluctuations!!.relation.text)
                .append(screenOverallScoreFluctuations!!.value)
        }
        if (meetingRateFluctuations != null) {
            sb.append(" and t2.meeting_rate").append(meetingRateFluctuations!!.relation.text)
                .append(meetingRateFluctuations!!.value)
        }
        if (investmentRateFluctuations != null) {
            sb.append(" and t2.investment_rate").append(investmentRateFluctuations!!.relation.text)
                .append(investmentRateFluctuations!!.value)
        }
        if (riskRateFluctuations != null) {
            sb.append(" and t2.risk_rate").append(riskRateFluctuations!!.relation.text)
                .append(riskRateFluctuations!!.value)
        }
        if (keymanRateFluctuations != null) {
            sb.append(" and t2.key_man_rate").append(keymanRateFluctuations!!.relation.text)
                .append(keymanRateFluctuations!!.value)
        }
        if (businessRateFluctuations != null) {
            sb.append(" and t2.business_rate").append(businessRateFluctuations!!.relation.text)
                .append(businessRateFluctuations!!.value)
        }

        if (annualizedReturns != null) {
            sb.append(" and f.year_nav").append(annualizedReturns!!.relation.text)
                .append(annualizedReturns!!.value)
        }
        if (StringUtils.hasText(fundName)) {
            sb.append(" and f.fund_name like '%${fundName!!}%'")
        }
        if (StringUtils.hasText(fundShortName)) {
            sb.append(" and f.fund_short_name like '%${fundShortName!!}%'")
        }
        return sb.toString()
    }

    private fun buildSortBy(): String =
        if (sort != null) {
            if (!NAME_MAP.containsKey(sort!!.field)) {
                throw SystemException("不支持的排序方式")
            }
            when (sort!!.sortType) {
                SortType.DESC -> "order by ${NAME_MAP[sort!!.field]} desc"
                SortType.ASC -> "order by ${NAME_MAP[sort!!.field]} asc"
            }
        } else {
            "order by f.fund_name asc"
        }


    private fun screenOverallRateConditionFilter(): String {
        return if (screenOverallRateCondition == null) {
            ""
        } else {
            "and f.fund_id in ( select distinct t2.fund_id from  t_fund_depth_research t2  where t2.screen_overall_rate ${screenOverallRateCondition!!.relation.text} ${screenOverallRateCondition!!.value} )"
        }
    }

    private fun parentAumFilter(): String {
        return if (parentAumCondition == null || parentAumCondition!!.isEmpty()) {
            ""
        } else {
            val filter = StringBuilder("and (  ")
            val conditions = parentAumCondition!!.joinToString(" and ") { condition ->
                " f.parent_aum like '%${condition}%'"
            }
            filter.append(conditions).append(" )")
            filter.toString()
        }
    }


    private fun childAumFilter(): String {
        return if (childAumCondition == null || childAumCondition!!.isEmpty()) {
            ""
        } else {
            val filter = StringBuilder("and (  ")
            val conditions = childAumCondition!!.joinToString(" and ") { condition ->
                " f.child_aum like '%${condition}%'"
            }
            filter.append(conditions).append(" )")
            filter.toString()
        }
    }
}

open class NumberRangeQuery {

    open lateinit var relation: NumberRelation

    open lateinit var value: BigDecimal


}
